import 'dart:io';

import 'package:path_provider/path_provider.dart';

class AppUpdaterStorage<T> {
  AppUpdaterStorage({
    required this.fileName,
    required this.readFrom,
    required this.writeTo,
  }) : assert(fileName.isNotEmpty);

  final String fileName;
  final T? Function(String) readFrom;
  final String Function(T) writeTo;

  Future<File> get file {
    return getApplicationSupportDirectory().then((Directory directory) {
      return File('${directory.path}/$fileName');
    });
  }

  Future<void> delete() {
    return file.then((File file) {
      if (file.existsSync()) {
        return file.delete();
      }
      return Future<void>.value();
    });
  }

  Future<File> write(T? data) {
    return file.then((File file) {
      final String encoded = data == null ? '' : writeTo(data);
      return file.writeAsString(encoded, mode: FileMode.writeOnly);
    });
  }

  Future<T?> get read {
    return file.then((File file) {
      if (file.existsSync()) {
        return file.readAsString();
      }
      return Future<String?>.value();
    }).then((String? content) {
      if (content != null && content.isNotEmpty) {
        return readFrom(content);
      }
      return null;
    });
  }

  Future<bool> update(T? Function(T?) updater) {
    return read.then((T? data) {
      final T? updated = updater(data);
      if (data != updated) {
        return write(updated).then((File file) => true);
      }
      return false;
    });
  }
}
